#include <fstream>
#include <iostream>
#include <common/Logger.h>
#include <server/PollServer.h>
#include <server/TcpRecver.h>
#include <server/CmdDecoder.h>
#include <server/CmdHandler.h>
#include "ServerStatistic.h"

CServerStatistic::CServerStatistic(CMainServer & mainServer)
    : CThreadPool(1)
    , config_(mainServer.config_)
    , addingFd_(mainServer.addingFd_)
    , readableFdQue_(mainServer.readableFdQue_)
    , fdSockMap_(mainServer.fdSockMap_)
    , decodableFdQue_(mainServer.decodableFdQue_)
    , queryCmdQue_(mainServer.queryCmdQue_)
    , recver(*mainServer.recver)
    , cmdDecoder(*mainServer.cmdDecoder)
    , cmdHandler(*mainServer.cmdHandler)
{}

void CServerStatistic::Init()
{
    serverStatusFile_           = config_.GetString("server.status.file.name");
    serverStatusTimeInterval_   = config_.GetInt("server.status.time.interval",30,5);
}

void CServerStatistic::Reconfig()
{
    serverStatusTimeInterval_   = config_.GetInt("server.status.time.interval",30,5);
}

void CServerStatistic::ShowConfig() const
{
    using namespace std;
    cout<<"\nServerStatistic :\n"
        <<"  serverStatusFile_ = "<<serverStatusFile_<<endl
        <<"  serverStatusTimeInterval_ = "<<serverStatusTimeInterval_<<endl;
}

int CServerStatistic::doIt()
{
    LOCAL_LOGGER(logger,"CServerStatistic::doIt");
    //header info
    DEBUG("open server status file "<<serverStatusFile_);
    std::ofstream outf(serverStatusFile_.c_str());
    if(!outf.is_open()){
        ERROR("cannot open server status file="<<serverStatusFile_);
    }else{
        outf<<"Time"
            <<"\t"<<"addingFd_.Size()"<<"\t"<<"addingFd_.TopSize()"
            <<"\t"<<"readableFdQue_.Size()"<<"\t"<<"readableFdQue_.TopSize()"
            <<"\t"<<"fdSockMap_.Size()"
            <<"\t"<<"decodableFdQue_.Size()"<<"\t"<<"decodableFdQue_.TopSize()"
            <<"\t"<<"queryCmdQue_.Size()"<<"\t"<<"queryCmdQue_.TopSize()"
            <<"\t"<<"recver.ActiveCount()"<<"\t"<<"recver.ActiveMax()"
            <<"\t"<<"cmdDecoder.ActiveCount()"<<"\t"<<"cmdDecoder.ActiveMax()"
            <<"\t"<<"cmdHandler.ActiveCount()"<<"\t"<<"cmdHandler.ActiveMax()"
            <<std::endl;
        outf.close();
    }
    for(;;){
        sleep(serverStatusTimeInterval_);
        DEBUG("open server status file "<<serverStatusFile_<<" and write");
        outf.open(serverStatusFile_.c_str(),std::ios_base::app);
        if(!outf.is_open()){
            ERROR("cannot open server status file="<<serverStatusFile_);
        }else{
            outf<<Tools::TimeString(time(0));
            outf<<"\t"<<addingFd_.Size()<<"\t"<<addingFd_.TopSize();
            outf<<"\t"<<readableFdQue_.Size()<<"\t"<<readableFdQue_.TopSize();
            outf<<"\t"<<fdSockMap_.Size();
            outf<<"\t"<<decodableFdQue_.Size()<<"\t"<<decodableFdQue_.TopSize();
            outf<<"\t"<<queryCmdQue_.Size()<<"\t"<<queryCmdQue_.TopSize();
            outf<<"\t"<<recver.ActiveCount()<<"\t"<<recver.ActiveMax();
            outf<<"\t"<<cmdDecoder.ActiveCount()<<"\t"<<cmdDecoder.ActiveMax();
            outf<<"\t"<<cmdHandler.ActiveCount()<<"\t"<<cmdHandler.ActiveMax();
            outf<<std::endl;
            outf.close();
            addingFd_.ResetTopSize();
            readableFdQue_.ResetTopSize();
            decodableFdQue_.ResetTopSize();
            queryCmdQue_.ResetTopSize();
            recver.ResetActive();
            cmdDecoder.ResetActive();
            cmdHandler.ResetActive();
        }
    }
    return 0;
}
